<template>
  <div class="viewer-page">
    <!-- 顶部工具栏 -->
    <div class="viewer-header">
      <!-- 左侧 LOGO 和患者信息 -->
      <div class="header-left">
        <div class="viewer-logo">
          <svg class="svg-logo" viewBox="0 0 120 40" xmlns="http://www.w3.org/2000/svg">
            <text x="10" y="28" font-size="24" font-weight="bold" fill="#409EFF">UCare</text>
          </svg>
        </div>
        
        <!-- 可切换显示的患者信息 -->
        <div class="patient-info-toggle" @click="togglePatientInfo">
          <i class="el-icon-user"></i>
          <span>患者信息</span>
        </div>
      </div>
      
      <!-- 中间的序列选择器 -->
      <div class="header-center">
        <div class="series-selector" v-if="seriesList.length > 1">
          <el-select 
            v-model="activeSeries" 
            placeholder="选择序列" 
            size="small"
            @change="loadSeries">
            <el-option
              v-for="series in seriesList"
              :key="series.ID"
              :label="formatSeriesLabel(series)"
              :value="series.ID">
            </el-option>
          </el-select>
        </div>
      </div>
      
      <!-- 右侧操作按钮 -->
      <div class="header-right">
        <el-button size="small" type="primary" plain @click="$router.push('/patients')">
          <i class="el-icon-back"></i> 返回列表
        </el-button>
      </div>
    </div>
    
    <!-- 主要内容区域 -->
    <div class="viewer-content">
      <!-- 左侧工具栏 -->
      <div class="tools-sidebar">
        <div class="tool-group">
          <button 
            class="tool-btn" 
            :class="{ 'active': activeTool === 'StackScroll' }"
            @click="setActiveTool('StackScroll')"
            title="滚动浏览">
            <i class="el-icon-d-caret"></i>
            <span>滚动</span>
          </button>
          
          <button 
            class="tool-btn" 
            :class="{ 'active': activeTool === 'Zoom' }"
            @click="setActiveTool('Zoom')"
            title="缩放图像">
            <i class="el-icon-zoom-in"></i>
            <span>缩放</span>
          </button>
          
          <button 
            class="tool-btn" 
            :class="{ 'active': activeTool === 'Pan' }"
            @click="setActiveTool('Pan')"
            title="平移图像">
            <i class="el-icon-rank"></i>
            <span>平移</span>
          </button>
          
          <button 
            class="tool-btn" 
            :class="{ 'active': activeTool === 'WwwcTool' }"
            @click="setActiveTool('WwwcTool')"
            title="窗宽窗位调整">
            <i class="el-icon-picture"></i>
            <span>窗位</span>
          </button>
        </div>
        
        <div class="tool-group">
          <button 
            class="tool-btn"
            @click="resetView"
            title="重置视图">
            <i class="el-icon-refresh"></i>
            <span>重置</span>
          </button>
          
          <button 
            class="tool-btn"
            @click="invertImage"
            title="反转图像">
            <i class="el-icon-sort"></i>
            <span>反转</span>
          </button>
          
          <button 
            class="tool-btn"
            @click="toggleFullscreen"
            title="全屏显示">
            <i class="el-icon-full-screen"></i>
            <span>全屏</span>
          </button>
        </div>
      </div>
      
      <!-- 中央影像显示区域 -->
      <div class="viewer-container">
        <div class="viewer-item" ref="viewerContainer">
          <div 
            class="cornerstone-element" 
            ref="viewer1" 
            @contextmenu.prevent="handleContextMenu"
            @mousedown="handleMouseDown"
            @mouseup="handleMouseUp"
            @mousemove="handleMouseMove"
            @wheel="handleMouseWheel">
          </div>
          
          <!-- 患者信息浮层 -->
          <div class="patient-info-overlay" v-if="showPatientInfo">
            <div class="overlay-header">
              <span>患者信息</span>
              <i class="el-icon-close" @click="showPatientInfo = false"></i>
            </div>
            <div class="overlay-content">
              <div class="info-row">
                <span class="info-label">姓名:</span>
                <span class="info-value">{{ patientName }}</span>
              </div>
              <div class="info-row" v-if="patientInfo">
                <span class="info-label">性别:</span>
                <span class="info-value">{{ patientInfo.sex || '未知' }}</span>
              </div>
              <div class="info-row" v-if="patientInfo">
                <span class="info-label">出生日期:</span>
                <span class="info-value">{{ formatBirthDate(patientInfo.birthDate) || '未知' }}</span>
              </div>
              <div class="info-row" v-if="studyMetadata">
                <span class="info-label">检查日期:</span>
                <span class="info-value">{{ formatStudyDate(studyMetadata.MainDicomTags.StudyDate) }}</span>
              </div>
              <div class="info-row" v-if="studyMetadata">
                <span class="info-label">检查描述:</span>
                <span class="info-value">{{ studyMetadata.MainDicomTags.StudyDescription || '无描述' }}</span>
              </div>
            </div>
          </div>
          
          <!-- 图像信息覆盖层 -->
          <div class="image-overlay" v-if="currentImageIndex >= 0">
            <div class="image-info">
              <div class="series-description">{{ currentSeriesDescription }}</div>
              <div class="image-count">{{ currentImageIndex + 1 }} / {{ totalImages }}</div>
              <div class="image-details" v-if="imageMetadata">
                {{ imageMetadata.modality }} {{ imageMetadata.seriesNumber }}
                {{ imageMetadata.instanceNumber }}
                <span v-if="imageMetadata.thickness">{{ imageMetadata.thickness }}mm</span>
              </div>
            </div>
          </div>
          
          <!-- 缩放信息提示 -->
          <div class="zoom-info" v-if="showZoomInfo">
            缩放: {{ zoomLevel.toFixed(2) }}x
          </div>
          
          <!-- 窗宽窗位信息 -->
          <div class="wwwc-info" v-if="showWwwcInfo">
            WW: {{ windowWidth }} / WC: {{ windowCenter }}
          </div>
          
          <!-- 底部进度条 -->
          <div class="bottom-progress-bar" v-if="!loading && totalImages > 0">
            <el-button 
              size="medium" 
              icon="el-icon-arrow-up" 
              @click="previousImage" 
              :disabled="currentImageIndex <= 0">
            </el-button>
            
            <div class="horizontal-slider">
              <el-slider 
                v-model="currentImageIndex" 
                :min="0" 
                :max="totalImages - 1" 
                :show-tooltip="true"
                :format-tooltip="value => `${value + 1}/${totalImages}`"
                @change="handleSliderChange">
              </el-slider>
            </div>
            
            <el-button 
              size="medium" 
              icon="el-icon-arrow-down" 
              @click="nextImage" 
              :disabled="currentImageIndex >= totalImages - 1">
            </el-button>
            
            <div class="slice-info">
              {{ currentImageIndex + 1 }} / {{ totalImages }}
            </div>
          </div>
          
          <!-- 加载指示器 -->
          <div class="loading-indicator" v-if="loading">
            <el-progress 
              type="circle" 
              :percentage="loadingPercentage" 
              :width="80"
              :stroke-width="8"
              :show-text="true"
              status="success">
            </el-progress>
            <div class="loading-text">
              正在加载影像 ({{ loadedImages }}/{{ totalImages }})
            </div>
          </div>
        </div>
      </div>
      
      <!-- 右侧 AI 分析面板 -->
      <div class="ai-panel" :class="{ 'collapsed': aiPanelCollapsed }">
        <div class="panel-toggle" @click="toggleAiPanel">
          <i :class="aiPanelCollapsed ? 'el-icon-arrow-left' : 'el-icon-arrow-right'"></i>
        </div>
        
        <div class="panel-content" v-if="!aiPanelCollapsed">
          <div class="panel-header">
            <h3>AI 分析结果</h3>
          </div>
          
          <div class="panel-body">
            <div class="placeholder-text">
              <i class="el-icon-data-analysis"></i>
              <p>AI 分析结果将在此显示</p>
            </div>
          </div>
        </div>
      </div>
    </div>
    
    <!-- 错误对话框 -->
    <el-dialog
      title="错误"
      :visible.sync="showErrorDialog"
      width="30%">
      <span>{{ errorMessage }}</span>
      <span slot="footer" class="dialog-footer">
        <el-button @click="showErrorDialog = false">关闭</el-button>
        <el-button type="primary" @click="retryLoading">重试</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
import orthancService from '@/services/orthanc'
import cornerstone from 'cornerstone-core'
import cornerstoneMath from 'cornerstone-math'
import cornerstoneTools from 'cornerstone-tools'
import cornerstoneWADOImageLoader from 'cornerstone-wado-image-loader'
import dicomParser from 'dicom-parser'
import Hammer from 'hammerjs'
import '@/styles/viewerPage.css'  // 引入独立的样式文件
import imageLoaderService from '@/services/imageLoaderService'

export default {
  name: 'ViewerPage',
  props: {
    patientId: {
      type: String,
      required: true
    },
    studyId: {
      type: String,
      required: true
    },
    preloadStrategy: {
      type: String,
      default: 'auto'
    }
  },
  data() {
    return {
      loading: true,
      patientName: '加载中...',
      seriesList: [],
      activeSeries: null,
      imageIds: [],
      currentImageIndex: 0,
      totalImages: 0,
      viewportElement: null,
      activeTool: 'StackScroll',  // 默认选择滚动工具
      stack: null,
      loadedImages: 0,
      patientInfo: null,
      currentSeriesDescription: '',
      imageMetadata: null,
      isFullscreen: false,
      showErrorDialog: false,
      errorMessage: '',
      resizeObserver: null,
      loadingQueue: [],
      preloadRange: 10, // 预加载前后10张图像
      windowWidth: 400,
      windowCenter: 40,
      annotations: [],
      showImageInfo: false,
      studyList: [],
      activeStudyId: '',
      studyMetadata: null,
      
      // 新增缩放相关状态
      isRightMouseDown: false,
      lastMousePosition: { x: 0, y: 0 },
      zoomLevel: 1.0,
      showZoomInfo: false,
      zoomInfoTimeout: null,
      
      // 新增UI状态
      showPatientInfo: false,
      aiPanelCollapsed: false,
      showWwwcInfo: false,
      wwwcInfoTimeout: null
    }
  },
  
  computed: {
    loadingPercentage() {
      return Math.min(Math.round(this.loadedImages / Math.max(this.totalImages, 1) * 100), 100);
    }
  },
  
  watch: {
    // 监听当前图像变化，更新元数据
    currentImageIndex(newIndex) {
      this.updateImageMetadata(newIndex)
    }
  },
  async mounted() {
    console.log('ViewerPage 组件挂载...')
    try {
      // 初始化 Cornerstone
      await this.initializeCornerstone()
      
      // 初始化查看器
      this.initializeViewer()
      
      // 添加窗口大小变化监听
      this.setupResizeObserver()
      
      // 添加键盘快捷键
      this.setupKeyboardShortcuts()
      
      // 获取患者信息
      try {
        this.patientInfo = await orthancService.getPatientInfo(this.patientId)
        this.patientName = this.patientInfo.name || '未知患者'
      } catch (error) {
        console.error('获取患者信息失败:', error)
        this.patientName = '未知患者'
      }
      
      // 获取患者的所有检查
      await this.loadPatientStudies()
      
      // 设置鼠标事件
      this.$nextTick(() => {
        this.setupMouseEvents();
      });
      
      // 默认选择滚动工具
      this.activeTool = 'StackScroll';
      
      // 添加鼠标右键事件监听
      document.addEventListener('mousedown', this.handleGlobalMouseDown);
      document.addEventListener('mouseup', this.handleGlobalMouseUp);
      document.addEventListener('mousemove', this.handleGlobalMouseMove);
    } catch (error) {
      console.error('初始化查看器失败:', error)
      this.errorMessage = error.message || '未知错误'
      this.showErrorDialog = true
      this.loading = false
    }
  },
  beforeDestroy() {
    // 清理 Cornerstone 资源
    if (this.viewportElement) {
      cornerstone.disable(this.viewportElement)
    }
    
    // 移除窗口大小变化监听
    if (this.resizeObserver) {
      this.resizeObserver.disconnect()
    }
    
    // 移除键盘快捷键
    document.removeEventListener('keydown', this.handleKeyDown)
    
    // 移除全屏变化监听
    document.removeEventListener('fullscreenchange', this.handleFullscreenChange)
    document.removeEventListener('webkitfullscreenchange', this.handleFullscreenChange)
    document.removeEventListener('mozfullscreenchange', this.handleFullscreenChange)
    document.removeEventListener('MSFullscreenChange', this.handleFullscreenChange)
    
    // 移除事件监听器
    if (this.viewportElement) {
      this.viewportElement.removeEventListener('mousedown', this.handleMouseDown);
      this.viewportElement.removeEventListener('mouseup', this.handleMouseUp);
      this.viewportElement.removeEventListener('mousemove', this.handleMouseMove);
      this.viewportElement.removeEventListener('wheel', this.handleMouseWheel);
    }
    
    // 清理cornerstone资源
    if (this.viewportElement) {
      cornerstone.disable(this.viewportElement);
    }
    
    // 清空图像缓存
    cornerstone.imageCache.purgeCache();
    
    // 停止所有正在进行的请求
    cornerstoneWADOImageLoader.wadouri.dataSetCacheManager.purge();
    
    // 清理Web Workers
    if (cornerstoneWADOImageLoader.webWorkerManager) {
      cornerstoneWADOImageLoader.webWorkerManager.terminate();
    }
    
    // 移除事件监听器
    window.removeEventListener('resize', this.onWindowResize);
    
    // 清除任何可能的计时器
    if (this._scrollTimer) {
      clearTimeout(this._scrollTimer);
    }
    
    // 移除鼠标右键事件监听
    document.removeEventListener('mousedown', this.handleGlobalMouseDown);
    document.removeEventListener('mouseup', this.handleGlobalMouseUp);
    document.removeEventListener('mousemove', this.handleGlobalMouseMove);
    
    // 清除缩放信息显示的定时器
    if (this.zoomInfoTimeout) {
      clearTimeout(this.zoomInfoTimeout);
    }
  },
  methods: {
    async initializeCornerstone() {
      console.log('初始化 Cornerstone 库...')
      
      // 设置外部依赖
      console.log('设置 Cornerstone 外部依赖...')
      cornerstoneTools.external.cornerstone = cornerstone
      cornerstoneTools.external.cornerstoneMath = cornerstoneMath
      cornerstoneTools.external.Hammer = Hammer
      
      // 初始化工具 - 只保留必要的滚动工具
      console.log('初始化 Cornerstone 工具...')
      cornerstoneTools.init({
        showSVGCursors: true,
        mouseEnabled: true,
        touchEnabled: true
      })
      
      // 只注册必要的滚动工具
      cornerstoneTools.addTool(cornerstoneTools.StackScrollTool)
      cornerstoneTools.addTool(cornerstoneTools.StackScrollMouseWheelTool)
      
      // 配置 WADO 图像加载器
      console.log('配置 WADO 图像加载器...')
      cornerstoneWADOImageLoader.external.cornerstone = cornerstone
      cornerstoneWADOImageLoader.external.dicomParser = dicomParser
      
      // 优化图像加载器配置
      const config = {
        maxWebWorkers: Math.max(navigator.hardwareConcurrency || 4, 4), // 使用至少4个Web Worker
        startWebWorkersOnDemand: false, // 立即启动Web Worker
        webWorkerTaskPriority: 5, // 提高Web Worker任务优先级
        taskConfiguration: {
          decodeTask: {
            initializeCodecsOnStartup: true,
            strict: false // 非严格模式可能更快
          }
        }
      }
      
      cornerstoneWADOImageLoader.webWorkerManager.initialize(config)
      
      // 注册自定义图像加载器
      cornerstone.registerImageLoader('wadouri', cornerstoneWADOImageLoader.wadouri.loadImage)
      cornerstone.registerImageLoader('mock', this.mockImageLoader)
      
      console.log('Cornerstone 初始化完成')
    },
    
    initializeViewer() {
      try {
        console.log('初始化 Cornerstone 查看器...');
        
        // 获取查看器元素
        console.log('初始化 Cornerstone 查看器元素');
        this.viewportElement = this.$refs.viewer1;
        
        // 启用元素
        cornerstone.enable(this.viewportElement);
        
        // 添加工具
        this.addCornerstoneTools(this.viewportElement);
        
        console.log('Cornerstone 查看器初始化完成');
        return true;
      } catch (error) {
        console.error('初始化查看器失败:', error);
        return false;
      }
    },
    
    setupEventListeners() {
      // 监听图像渲染事件
      this.viewportElement.addEventListener('cornerstoneimagerendered', this.onImageRendered)
      
      // 监听窗口大小变化
      window.addEventListener('resize', this.handleResize)
      
      // 监听全屏变化
      document.addEventListener('fullscreenchange', this.handleFullscreenChange)
      document.addEventListener('webkitfullscreenchange', this.handleFullscreenChange)
      document.addEventListener('mozfullscreenchange', this.handleFullscreenChange)
      document.addEventListener('MSFullscreenChange', this.handleFullscreenChange)
    },
    
    setupResizeObserver() {
      // 使用ResizeObserver监听元素大小变化
      if (window.ResizeObserver) {
        this.resizeObserver = new ResizeObserver(() => {
          if (this.viewportElement) {
            cornerstone.resize(this.viewportElement)
          }
        })
        
        this.resizeObserver.observe(this.viewportElement)
      }
    },
    
    setupKeyboardShortcuts() {
      // 添加键盘快捷键
      document.addEventListener('keydown', this.handleKeyDown)
    },
    
    handleKeyDown(event) {
      // 处理键盘快捷键
      switch (event.key) {
        case 'ArrowLeft':
          this.previousImage()
          event.preventDefault()
          break
        case 'ArrowRight':
          this.nextImage()
          event.preventDefault()
          break
        case 'ArrowUp':
          this.adjustWindowLevel(0, 10)  // 增加窗位
          event.preventDefault()
          break
        case 'ArrowDown':
          this.adjustWindowLevel(0, -10)  // 减少窗位
          event.preventDefault()
          break
        case '+':
        case '=':
          this.adjustWindowLevel(10, 0)  // 增加窗宽
          event.preventDefault()
          break
        case '-':
          this.adjustWindowLevel(-10, 0)  // 减少窗宽
          event.preventDefault()
          break
        case 'r':
        case 'R':
          this.resetView()  // 重置视图
          event.preventDefault()
          break
        case 'f':
        case 'F':
          this.toggleFullscreen()  // 全屏
          event.preventDefault()
          break
      }
    },
    
    handleResize() {
      // 调整视图大小
      if (this.viewportElement) {
        cornerstone.resize(this.viewportElement)
      }
    },
    
    handleFullscreenChange() {
      // 检测当前是否处于全屏状态
      this.isFullscreen = !!(
        document.fullscreenElement ||
        document.webkitFullscreenElement ||
        document.mozFullScreenElement ||
        document.msFullscreenElement
      )
      
      // 调整视图大小
      this.handleResize()
    },
    
    onImageRendered(event) {
      // 获取渲染的图像
      const viewport = cornerstone.getViewport(event.target)
      
      // 更新窗宽窗位值
      this.windowWidth = Math.round(viewport.voi.windowWidth)
      this.windowCenter = Math.round(viewport.voi.windowCenter)
      
      // 更新图像元数据
      this.updateImageMetadata(this.currentImageIndex)
    },
    
    adjustWindowLevel(widthDelta, centerDelta) {
      if (!this.viewportElement) return
      
      // 获取当前视口
      const viewport = cornerstone.getViewport(this.viewportElement)
      
      // 调整窗宽窗位
      viewport.voi.windowWidth += widthDelta
      viewport.voi.windowCenter += centerDelta
      
      // 确保窗宽为正值
      if (viewport.voi.windowWidth < 1) {
        viewport.voi.windowWidth = 1
      }
      
      // 更新视口
      cornerstone.setViewport(this.viewportElement, viewport)
    },
    
    async loadPatientStudies() {
      try {
        console.log('加载患者的所有检查:', this.patientId)
        this.loading = true
        
        // 获取患者的所有检查
        const studies = await orthancService.getPatientStudies(this.patientId)
        
        if (studies && studies.length > 0) {
          // 按检查日期排序，最新的排在前面
          this.studyList = studies.sort((a, b) => {
            const dateA = a.MainDicomTags.StudyDate || '19000101'
            const dateB = b.MainDicomTags.StudyDate || '19000101'
            return dateB.localeCompare(dateA) // 降序排列
          })
          
          console.log('患者检查列表:', this.studyList)
          
          // 默认选择最新的检查
          this.activeStudyId = this.studyList[0].ID
          
          // 加载选中的检查
          await this.loadStudy(this.activeStudyId)
        } else {
          console.error('未找到患者检查')
          this.errorMessage = '未找到患者检查'
          this.showErrorDialog = true
        }
        
        this.loading = false
      } catch (error) {
        console.error('加载患者检查失败:', error)
        this.errorMessage = error.message || '加载患者检查失败'
        this.showErrorDialog = true
        this.loading = false
      }
    },
    
    async loadStudy(studyId) {
      try {
        console.log('加载检查:', studyId)
        this.loading = true
        
        // 清空当前序列和图像
        this.seriesList = []
        this.activeSeries = null
        this.imageIds = []
        this.currentImageIndex = 0
        this.totalImages = 0
        
        // 获取检查的所有序列
        const series = await orthancService.getStudySeries(studyId)
        
        if (series && series.length > 0) {
          // 处理序列数据
          this.seriesList = series.map(s => ({
            id: s.ID,
            description: s.MainDicomTags.SeriesDescription || '未命名序列',
            number: s.MainDicomTags.SeriesNumber || '0',
            modality: s.MainDicomTags.Modality || 'Unknown',
            instances: s.Instances || []
          }))
          
          console.log('检查序列列表:', this.seriesList)
          
          // 默认选择第一个序列
          this.activeSeries = this.seriesList[0].id
          
          // 加载选中的序列
          await this.loadSeries(this.activeSeries)
        } else {
          console.error('未找到检查序列')
          this.errorMessage = '未找到检查序列'
          this.showErrorDialog = true
        }
        
        this.loading = false
      } catch (error) {
        console.error('加载检查失败:', error)
        this.errorMessage = error.message || '加载检查失败'
        this.showErrorDialog = true
        this.loading = false
      }
    },
    
    async loadSeries(seriesId) {
      console.log('加载序列', seriesId);
      this.loading = true;
      this.loadedImages = 0;
      this.imageIds = [];
      
      // 开始计时
      const startTime = performance.now();
      
      try {
        // 获取序列信息
        const series = this.seriesList.find(s => s.id === seriesId);
        if (series) {
          this.currentSeriesDescription = series.description || seriesId;
        }
        
        // 检查是否已经有实例数据
        let instances = [];
        if (series && series.instances && series.instances.length > 0) {
          console.log('使用已缓存的实例数据');
          instances = series.instances;
        } else {
          // 获取序列的实例
          instances = await orthancService.getInstancesForSeries(seriesId);
          
          // 更新序列的实例缓存
          if (series) {
            series.instances = instances;
          }
        }
        
        // console.log('获取到实例:', instances);
        
        if (!instances || instances.length === 0) {
          throw new Error('未找到实例');
        }
        
        // 设置图像ID列表
        this.imageIds = instances.map(instance => {
          // 确保我们有正确的实例ID
          const instanceId = instance.ID || instance.id || instance;
          return `wadouri:/api/instances/${instanceId}/file`;
        });
        
        this.totalImages = this.imageIds.length;
        this.currentImageIndex = 0;
        
        // 加载第一张图像
        this.loadAndDisplayImage(this.imageIds[0]);
        
        // 启用预加载功能
        this.preloadImages(this.imageIds);
        
        // 设置活动序列
        this.activeSeries = seriesId;
        
        // 结束计时并打印加载时间
        const loadTime = performance.now() - startTime;
        console.log(`序列加载完成，耗时: ${loadTime.toFixed(2)}ms`);
        
        this.loading = false;
        return true;
      } catch (error) {
        console.error('加载序列失败:', error);
        this.loading = false;
        this.errorMessage = '加载序列失败: ' + (error.message || '未知错误');
        this.showErrorDialog = true;
        
        // 加载模拟图像作为备选
        this.loadMockImage();
        return false;
      }
    },
    
    async loadAndDisplayImage(imageId) {
      if (!imageId) return null;
      
      try {
        console.log('加载图像', imageId);
        const startTime = performance.now();
        
        // 检查图像是否已经缓存
        if (!cornerstone.imageCache.cachedImages[imageId]) {
          // 如果图像未缓存，先显示加载状态但不清除当前图像
          this.imageLoading = true;
        }
        
        // 加载图像
        const image = await cornerstone.loadAndCacheImage(imageId);
        
        // 显示图像
        cornerstone.displayImage(this.viewportElement, image);
        
        // 更新当前图像信息
        this.updateImageMetadata(this.currentImageIndex);
        
        // 重置加载状态
        this.imageLoading = false;
        
        // 记录加载时间
        const loadTime = performance.now() - startTime;
        console.log(`图像 ${imageId} 加载并显示完成，耗时: ${loadTime.toFixed(2)}ms`);
        
        return image;
      } catch (error) {
        console.error('加载图像失败:', error);
        this.imageLoading = false;
        return null;
      }
    },
    
    async displayImage(imageIndex) {
      if (imageIndex < 0 || imageIndex >= this.imageIds.length) {
        return;
      }
      
      // 如果已经在加载中且请求的是不同图像，取消当前操作
      if (this.imageLoading && this._lastRequestedIndex === imageIndex) {
        return;
      }
      
      // 记录当前请求的索引
      this._lastRequestedIndex = imageIndex;
      
      // 记录开始时间
      const displayStartTime = performance.now();
      
      try {
        // 更新当前索引
        this.currentImageIndex = imageIndex;
        
        // 获取图像ID
        const imageId = this.imageIds[imageIndex];
        
        // 显示加载状态
        this.imageLoading = true;
        
        // 直接加载图像 - 不使用缓存检查，让cornerstone内部处理缓存
        try {
          const image = await cornerstone.loadAndCacheImage(imageId);
          
          // 如果在加载过程中又请求了新图像，则放弃当前操作
          if (this._lastRequestedIndex !== imageIndex) {
            return false;
          }
          
          // 使用requestAnimationFrame确保在下一帧渲染，减少闪烁
          window.requestAnimationFrame(() => {
            try {
              // 显示图像
              cornerstone.displayImage(this.viewportElement, image);
              
              // 更新图像元数据
              this.updateImageMetadata(imageIndex);
              
              // 关闭加载状态
              this.imageLoading = false;
              
              // 只在开发环境输出性能日志
              if (process.env.NODE_ENV === 'development') {
                const displayTime = performance.now() - displayStartTime;
                if (displayTime > 100) { // 只记录较慢的显示操作
                  console.log(`图像 ${imageIndex + 1}/${this.totalImages} 显示耗时: ${displayTime.toFixed(2)}ms`);
                }
              }
              
              // 预加载相邻图像
              this.preloadAdjacentImages(imageIndex);
            } catch (error) {
              console.error('显示图像失败:', error);
              this.imageLoading = false;
            }
          });
          
          return true;
        } catch (error) {
          console.error(`无法加载图像 ${imageId}:`, error);
          this.imageLoading = false;
          return false;
        }
      } catch (error) {
        console.error('显示图像失败:', error);
        this.imageLoading = false;
        return false;
      }
    },
    
    preloadAdjacentImages(currentIndex) {
      // 如果浏览器处于空闲状态，才进行预加载
      if ('requestIdleCallback' in window) {
        window.requestIdleCallback(() => {
          this._performAdjacentPreload(currentIndex);
        }, { timeout: 1000 });
      } else {
        // 降级处理
        setTimeout(() => {
          this._performAdjacentPreload(currentIndex);
        }, 100);
      }
    },
    
    _performAdjacentPreload(currentIndex) {
      // 预测用户可能的浏览方向
      const direction = this._detectScrollDirection(currentIndex);
      const preloadCount = 5; // 预加载数量
      
      const imagesToPreload = [];
      
      if (direction >= 0) {
        // 向前预加载
        for (let i = 1; i <= preloadCount; i++) {
          const index = currentIndex + i;
          if (index < this.totalImages) {
            imagesToPreload.push(this.imageIds[index]);
          }
        }
      } else {
        // 向后预加载
        for (let i = 1; i <= preloadCount; i++) {
          const index = currentIndex - i;
          if (index >= 0) {
            imagesToPreload.push(this.imageIds[index]);
          }
        }
      }
      
      // 使用低优先级加载
      imagesToPreload.forEach(imageId => {
        cornerstone.loadAndCacheImage(imageId, { priority: -5 });
      });
    },
    
    _detectScrollDirection(currentIndex) {
      // 简单的方向检测
      if (!this._lastIndex) {
        this._lastIndex = currentIndex;
        return 1; // 默认向前
      }
      
      const direction = currentIndex - this._lastIndex;
      this._lastIndex = currentIndex;
      return direction;
    },
    
    handleScroll(event) {
      if (!this.scrollThrottled) {
        this.scrollThrottled = true;
        
        // 确定滚动方向
        const delta = Math.max(-1, Math.min(1, (event.wheelDelta || -event.detail)));
        
        // 计算新的索引
        let newIndex = this.currentImageIndex;
        if (delta < 0) {
          newIndex = Math.min(this.imageIds.length - 1, newIndex + 1);
        } else {
          newIndex = Math.max(0, newIndex - 1);
        }
        
        // 如果索引变化了，显示新图像
        if (newIndex !== this.currentImageIndex) {
          this.displayImage(newIndex);
        }
        
        // 50ms后允许下一次滚动
        setTimeout(() => {
          this.scrollThrottled = false;
        }, 50);
      }
      
      // 阻止默认滚动行为
      event.preventDefault();
    },
    
    updateImageMetadata(index) {
      if (index < 0 || index >= this.imageIds.length) return
      
      try {
        const imageId = this.imageIds[index]
        
        // 对于模拟图像，创建模拟元数据
        if (imageId.startsWith('mock://')) {
          this.imageMetadata = {
            modality: 'MR',
            seriesNumber: '1',
            instanceNumber: (index + 1).toString(),
            thickness: '3.0',
            position: ''
          }
          return
        }
        
        // 对于真实图像，尝试获取元数据
        try {
          // 使用cornerstone.getImage获取当前显示的图像
          const image = cornerstone.getImage(this.viewportElement)
          
          if (image && image.data) {
            this.imageMetadata = {
              modality: image.data.string('x00080060') || 'Unknown',
              seriesNumber: image.data.string('x00200011') || '',
              instanceNumber: image.data.string('x00200013') || '',
              thickness: image.data.string('x00180050') || '',
              position: image.data.string('x00201041') || ''
            }
          } else {
            this.imageMetadata = null
          }
        } catch (error) {
          console.error('获取图像元数据失败:', error)
          this.imageMetadata = null
        }
      } catch (error) {
        console.error('更新图像元数据失败:', error)
        this.imageMetadata = null
      }
    },
    
    loadMockImage() {
      console.log('加载模拟图像...')
      this.loading = true
      
      // 创建模拟图像ID
      const mockImageIds = []
      for (let i = 0; i < 20; i++) {
        mockImageIds.push(`mock://${i}`)
      }
      
      this.imageIds = mockImageIds
      this.totalImages = mockImageIds.length
      this.currentImageIndex = 0
      this.currentSeriesDescription = '模拟序列'
      
      // 加载第一张模拟图像
      this.loadAndDisplayImage(mockImageIds[0])
        .then(() => {
          // 创建堆栈
          this.stack = {
            currentImageIdIndex: 0,
            imageIds: mockImageIds
          }
          
          // 设置堆栈
          cornerstoneTools.addToolState(
            this.viewportElement,
            'stack',
            this.stack
          )
          
          this.loading = false
        })
        .catch(error => {
          console.error('加载模拟图像失败:', error)
          this.loading = false
        })
    },
    
    mockImageLoader(imageId) {
      // 解析图像ID，获取索引
      const index = parseInt(imageId.split('//')[1], 10)
      
      // 创建模拟图像数据
      const width = 512
      const height = 512
      const pixelData = new Uint8Array(width * height)
      
      // 填充像素数据
      for (let y = 0; y < height; y++) {
        for (let x = 0; x < width; x++) {
          // 创建一些简单的图案
          pixelData[y * width + x] = (x + y + index * 20) % 256
          
          // 添加一些线条
          if ((x + index * 20) % 50 < 2 || (y + index * 20) % 50 < 2) {
            pixelData[y * width + x] = 200
          }
        }
      }
      
      // 创建cornerstone图像对象
      const image = {
        imageId: imageId,
        minPixelValue: 0,
        maxPixelValue: 255,
        slope: 1.0,
        intercept: 0,
        windowCenter: 127,
        windowWidth: 256,
        getPixelData: () => {
          const uint8Array = new Uint8Array(pixelData.buffer)
          return uint8Array
        },
        rows: height,
        columns: width,
        height: height,
        width: width,
        color: false,
        sizeInBytes: width * height * 4,
        columnPixelSpacing: 1.0,
        rowPixelSpacing: 1.0
      }
      
      return {
        promise: Promise.resolve(image)
      }
    },
    
    previousImage() {
      if (this.currentImageIndex > 0) {
        this.displayImage(this.currentImageIndex - 1);
      }
    },
    
    nextImage() {
      if (this.currentImageIndex < this.totalImages - 1) {
        this.displayImage(this.currentImageIndex + 1);
      }
    },
    
    resetView() {
      cornerstone.reset(this.viewportElement)
    },
    
    toggleFullscreen() {
      this.isFullscreen = !this.isFullscreen
      if (this.isFullscreen) {
        if (this.viewportElement.requestFullscreen) {
          this.viewportElement.requestFullscreen()
        } else if (this.viewportElement.mozRequestFullScreen) {
          this.viewportElement.mozRequestFullScreen()
        } else if (this.viewportElement.webkitRequestFullscreen) {
          this.viewportElement.webkitRequestFullscreen()
        } else if (this.viewportElement.msRequestFullscreen) {
          this.viewportElement.msRequestFullscreen()
        }
      } else {
        if (document.exitFullscreen) {
          document.exitFullscreen()
        } else if (document.mozCancelFullScreen) {
          document.mozCancelFullScreen()
        } else if (document.webkitCancelFullScreen) {
          document.webkitCancelFullScreen()
        } else if (document.msExitFullscreen) {
          document.msExitFullscreen()
        }
      }
    },
    
    formatDate(dateStr) {
      const date = new Date(dateStr)
      return date.toLocaleDateString()
    },
    
    retryLoading() {
      this.showErrorDialog = false
      this.loading = true
      this.loadStudyData()
    },
    
    preloadImages(imageIds) {
      if (!imageIds || imageIds.length === 0) return;
      
      // 重置加载计数
      this.loadedImages = 0;
      this.totalImages = imageIds.length;
      
      // 创建一个已加载图像的集合
      const loadedImages = new Set();
      
      // 记录开始时间
      const startTime = performance.now();
      
      // 配置并发加载参数
      const concurrentRequests = 6; // 并发请求数量
      
      if (process.env.NODE_ENV === 'development') {
        console.log(`开始高性能预加载 ${imageIds.length} 张图像，并发数: ${concurrentRequests}`);
      }
      
      // 创建加载队列
      let queue = [];
      let activeRequests = 0;
      let completed = 0;
      
      // 优先级排序函数 - 优先加载当前图像附近的图像
      const prioritizeImages = () => {
        const currentIndex = this.currentImageIndex;
        
        // 对图像ID进行排序，使当前图像附近的图像优先加载
        return [...imageIds].map((id, index) => ({
          id,
          priority: Math.abs(index - currentIndex) // 距离当前图像的距离作为优先级
        }))
        .sort((a, b) => a.priority - b.priority) // 按优先级排序
        .map(item => item.id);
      };
      
      // 处理队列中的下一个图像
      const processNext = () => {
        if (queue.length === 0 && activeRequests === 0) {
          // 所有图像已处理完成
          const totalTime = performance.now() - startTime;
          console.log(`✅ 所有图像加载完成，总耗时: ${totalTime.toFixed(2)}ms，平均每张: ${(totalTime / imageIds.length).toFixed(2)}ms`);
          return;
        }
        
        // 如果队列为空或已达到最大并发数，则返回
        if (queue.length === 0 || activeRequests >= concurrentRequests) {
          return;
        }
        
        // 从队列中取出下一个图像ID
        const imageId = queue.shift();
        
        // 如果图像已加载，则处理下一个
        if (loadedImages.has(imageId)) {
          processNext();
          return;
        }
        
        // 增加活动请求计数
        activeRequests++;
        
        // 加载图像
        cornerstone.loadAndCacheImage(imageId)
          .then(() => {
            // 标记为已加载
            loadedImages.add(imageId);
            completed++;
            
            // 更新加载计数 - 确保不超过总数
            this.loadedImages = Math.min(loadedImages.size, this.totalImages);
            
            if (process.env.NODE_ENV === 'development' && completed % 10 === 0) {
              // 确保显示的百分比不超过100%
              const percentage = Math.min(Math.round((this.loadedImages / this.totalImages) * 100), 100);
              console.log(`已加载 ${this.loadedImages}/${this.totalImages} 张图像 (${percentage}%)`);
            }
          })
          .catch(error => {
            console.error(`加载图像 ${imageId} 失败:`, error);
          })
          .finally(() => {
            // 减少活动请求计数
            activeRequests--;
            
            // 处理下一个图像
            processNext();
            
            // 如果还有空闲槽位，继续处理
            if (activeRequests < concurrentRequests) {
              processNext();
            }
          });
        
        // 如果还有空闲槽位，继续处理
        processNext();
      };
      
      // 初始化队列 - 优先加载当前图像附近的图像
      queue = prioritizeImages();
      
      // 开始处理队列
      for (let i = 0; i < concurrentRequests; i++) {
        processNext();
      }
      
      // 每隔一段时间重新排序队列，以适应用户浏览位置的变化
      const queueUpdateInterval = setInterval(() => {
        if (queue.length === 0) {
          clearInterval(queueUpdateInterval);
          return;
        }
        
        // 重新排序剩余队列中的图像
        queue = prioritizeImages().filter(id => !loadedImages.has(id));
      }, 2000);
    },
    
    // 添加鼠标滚动处理方法
    setupMouseEvents() {
      if (this.viewportElement) {
        this.viewportElement.addEventListener('mousedown', this.handleMouseDown);
        this.viewportElement.addEventListener('mouseup', this.handleMouseUp);
        this.viewportElement.addEventListener('mousemove', this.handleMouseMove);
        this.viewportElement.addEventListener('wheel', this.handleScroll);
      }
    },
    
    handleMouseDown(event) {
      // 处理右键缩放
      if (event.button === 2 && this.viewportElement) {
        this.isRightMouseDown = true;
        this.lastMousePosition = { x: event.clientX, y: event.clientY };
        
        // 添加鼠标样式
        document.body.classList.add('zooming');
        
        // 阻止事件冒泡
        event.stopPropagation();
        event.preventDefault();
      }
      
      // 不要阻止左键事件，让 Cornerstone 工具处理左键操作
    },
    
    handleMouseUp(event) {
      if (event.button === 2) {
        this.isRightMouseDown = false;
        
        // 移除鼠标样式
        document.body.classList.remove('zooming');
        
        // 阻止事件冒泡
        if (event.target === this.viewportElement) {
          event.stopPropagation();
          event.preventDefault();
        }
      }
    },
    
    handleMouseMove(event) {
      if (this.isRightMouseDown && this.viewportElement) {
        const deltaY = event.clientY - this.lastMousePosition.y;
        
        // 计算缩放因子 (向上移动放大，向下移动缩小)
        const scaleFactor = 1.0 - (deltaY * 0.01);
        
        // 获取当前视口
        const viewport = cornerstone.getViewport(this.viewportElement);
        
        // 应用缩放
        viewport.scale *= scaleFactor;
        
        // 限制缩放范围
        viewport.scale = Math.max(0.1, Math.min(10.0, viewport.scale));
        
        // 更新视口
        cornerstone.setViewport(this.viewportElement, viewport);
        
        // 更新缩放级别
        this.zoomLevel = viewport.scale;
        
        // 显示缩放信息
        this.showZoomInfo = true;
        
        // 清除之前的定时器
        if (this.zoomInfoTimeout) {
          clearTimeout(this.zoomInfoTimeout);
        }
        
        // 设置新的定时器，2秒后隐藏缩放信息
        this.zoomInfoTimeout = setTimeout(() => {
          this.showZoomInfo = false;
        }, 2000);
        
        // 更新鼠标位置
        this.lastMousePosition = { x: event.clientX, y: event.clientY };
        
        // 阻止事件冒泡
        event.stopPropagation();
        event.preventDefault();
      }
    },
    
    handleMouseWheel(event) {
      // 这里可以添加自定义滚轮行为
      // 默认由 StackScrollMouseWheel 工具处理
    },
    
    handleSliderChange(value) {
      this.displayImage(value);
    },
    
    addCornerstoneTools(element) {
      // 确保工具已正确注册
      cornerstoneTools.init({
        showSVGCursors: true
      });
      
      // 创建堆栈状态管理器
      const stack = {
        currentImageIdIndex: 0,
        imageIds: this.imageIds || []
      };
      
      // 将堆栈状态添加到元素
      cornerstoneTools.clearToolState(element, 'stack');
      cornerstoneTools.addToolState(element, 'stack', stack);
      
      // 添加所有需要的工具
      cornerstoneTools.addTool(cornerstoneTools.StackScrollMouseWheelTool);
      cornerstoneTools.addTool(cornerstoneTools.StackScrollTool);
      cornerstoneTools.addTool(cornerstoneTools.ZoomTool);
      cornerstoneTools.addTool(cornerstoneTools.PanTool);
      cornerstoneTools.addTool(cornerstoneTools.WwwcTool);
      
      // 设置默认工具 - 确保鼠标左键可以滚动
      cornerstoneTools.setToolActive('StackScrollMouseWheel', {});
      cornerstoneTools.setToolActive('StackScroll', { mouseButtonMask: 1 });
      
      // 监听图像渲染事件以更新缩放级别
      element.addEventListener('cornerstoneimagerendered', this.onImageRendered);
    },
    
    setActiveTool(toolName) {
      const element = this.viewportElement;
      if (!element) return;
        
      // 禁用所有工具
      cornerstoneTools.setToolDisabled('StackScroll');
      cornerstoneTools.setToolDisabled('Pan');
      cornerstoneTools.setToolDisabled('Zoom');
      cornerstoneTools.setToolDisabled('Wwwc');
      cornerstoneTools.setToolDisabled('StackScrollMouseWheel');
        
      // 启用选定的工具
      if (toolName === 'StackScroll') {
        cornerstoneTools.setToolActive('StackScroll', { mouseButtonMask: 1 });
        cornerstoneTools.setToolActive('StackScrollMouseWheel', {});
      } else if (toolName === 'Zoom') {
        cornerstoneTools.setToolActive('Zoom', { mouseButtonMask: 1 });
        cornerstoneTools.setToolActive('StackScrollMouseWheel', {});
      } else if (toolName === 'Pan') {
        cornerstoneTools.setToolActive('Pan', { mouseButtonMask: 1 });
        cornerstoneTools.setToolActive('StackScrollMouseWheel', {});
      } else if (toolName === 'WwwcTool') {
        cornerstoneTools.setToolActive('Wwwc', { mouseButtonMask: 1 });
        cornerstoneTools.setToolActive('StackScrollMouseWheel', {});
      }
        
      this.activeTool = toolName;
    },
    
    // 处理鼠标右键点击
    handleContextMenu(event) {
      // 阻止默认的右键菜单
      event.preventDefault();
    },
    
    // 切换患者信息显示
    togglePatientInfo() {
      this.showPatientInfo = !this.showPatientInfo;
    },
    
    // 切换AI面板
    toggleAiPanel() {
      this.aiPanelCollapsed = !this.aiPanelCollapsed;
    },
    
    // 格式化序列标签
    formatSeriesLabel(series) {
      const description = series.MainDicomTags.SeriesDescription || '未命名序列';
      const number = series.MainDicomTags.SeriesNumber || '';
      return `${number} - ${description}`;
    },
    
    // 反转图像
    invertImage() {
      if (this.viewportElement) {
        const viewport = cornerstone.getViewport(this.viewportElement);
        viewport.invert = !viewport.invert;
        cornerstone.setViewport(this.viewportElement, viewport);
      }
    },
    
    // 格式化出生日期
    formatBirthDate(birthDate) {
      if (!birthDate || birthDate === 'Unknown') return '';
      
      // 格式化日期，例如从 "19800101" 转换为 "1980-01-01"
      if (birthDate.length === 8) {
        return `${birthDate.substring(0, 4)}-${birthDate.substring(4, 6)}-${birthDate.substring(6, 8)}`;
      }
      
      return birthDate;
    },
    
    // 格式化检查日期
    formatStudyDate(dateStr) {
      if (!dateStr || dateStr === 'Unknown') return '未知日期';
      
      // 格式化日期，例如从 "20230101" 转换为 "2023-01-01"
      if (dateStr.length === 8) {
        return `${dateStr.substring(0, 4)}-${dateStr.substring(4, 6)}-${dateStr.substring(6, 8)}`;
      }
      
      return dateStr;
    },
    
    // 处理全局鼠标按下事件
    handleGlobalMouseDown(event) {
      if (event.button === 2 && this.viewportElement && this.viewportElement.contains(event.target)) {
        this.isRightMouseDown = true;
        this.lastMousePosition = { x: event.clientX, y: event.clientY };
        
        // 添加鼠标样式
        document.body.classList.add('zooming');
      }
    },
    
    // 处理全局鼠标释放事件
    handleGlobalMouseUp(event) {
      if (event.button === 2) {
        this.isRightMouseDown = false;
        
        // 移除鼠标样式
        document.body.classList.remove('zooming');
      }
    },
    
    // 处理全局鼠标移动事件
    handleGlobalMouseMove(event) {
      if (this.isRightMouseDown && this.viewportElement) {
        const deltaY = event.clientY - this.lastMousePosition.y;
        
        // 计算缩放因子 (向上移动放大，向下移动缩小)
        const scaleFactor = 1.0 - (deltaY * 0.01);
        
        // 获取当前视口
        const viewport = cornerstone.getViewport(this.viewportElement);
        
        // 应用缩放
        viewport.scale *= scaleFactor;
        
        // 限制缩放范围
        viewport.scale = Math.max(0.1, Math.min(10.0, viewport.scale));
        
        // 更新视口
        cornerstone.setViewport(this.viewportElement, viewport);
        
        // 更新缩放级别
        this.zoomLevel = viewport.scale;
        
        // 显示缩放信息
        this.showZoomInfo = true;
        
        // 清除之前的定时器
        if (this.zoomInfoTimeout) {
          clearTimeout(this.zoomInfoTimeout);
        }
        
        // 设置新的定时器，2秒后隐藏缩放信息
        this.zoomInfoTimeout = setTimeout(() => {
          this.showZoomInfo = false;
        }, 2000);
        
        // 更新鼠标位置
        this.lastMousePosition = { x: event.clientX, y: event.clientY };
      }
    },
  }
}
</script>

<style>
/* 所有样式已移至 src/styles/viewerPage.css */
</style> 